Skip to content

[caclmgrd]: Preserve externally-owned INPUT rules across CACL rebuild#396

Closed
Xichen96 wants to merge 2 commits into
sonic-net:masterfrom
Xichen96:dev/xichenlin/caclmgrd-dhcp-server-syslog
Closed

[caclmgrd]: Preserve externally-owned INPUT rules across CACL rebuild#396
Xichen96 wants to merge 2 commits into
sonic-net:masterfrom
Xichen96:dev/xichenlin/caclmgrd-dhcp-server-syslog

Conversation

@Xichen96

@Xichen96 Xichen96 commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Why I did it

Fixes sonic-net/sonic-buildimage#27584

caclmgrd flushes and rebuilds the host INPUT chain from CONFIG_DB on every control-plane ACL (CACL) change. The dhcp_server container (the only bridge-mode container) installs a docker0 syslog exception directly in the kernel:

-A INPUT -i docker0 -p udp --dport 514 -m comment --comment dhcp_server_syslog -j ACCEPT

That rule is not in CONFIG_DB, so the rebuild wipes it and the catch-all DROP then silently drops dhcp_server syslog until the container restarts.

Work item tracking
  • Microsoft ADO (number only): 38699922

How I did it

Make caclmgrd preserve INPUT rules it does not own instead of clobbering them:

  • caclmgrd never comments its own rules, so an iptables --comment marks an externally-owned rule. An explicit ignore list IGNORED_INPUT_RULE_COMMENTS (currently dhcp_server_syslog) says which to keep.
  • Before the flush, snapshot matching rules (iptables -S INPUT) and re-add them verbatim early in the rebuild — before any DROP.

Design notes (concerns considered)

  • Ownership boundary — the comment is the marker; caclmgrd only mirrors these rules (never creates/deletes them), so dhcp_server stays the sole owner via its existing start/stop add/remove. No container change.
  • No drop gap — policy is ACCEPT during the rebuild and the catch-all DROP is appended last, while the preserved rule is re-added early, so a DROP never coexists with the rule missing. Verified step-by-step that syslog is accepted at every point of the rebuild.
  • Container keeps control — the rule is re-added byte-identically (from iptables -S), so the container's own -C/-D still match it after a rebuild. Verified.
  • Contained scopecaclmgrd-only: it never writes CONFIG_DB, signals, or restarts dhcp_server. (A rare simultaneous flush/container-update can momentarily duplicate the rule; harmless and self-healing.)

How to verify it

  1. iptables -S INPUT | grep dhcp_server_syslog — rule present.
  2. sonic-db-cli CONFIG_DB HSET "ACL_TABLE|TEST_CACL" "policy_desc" "test" "type" "CTRLPLANE" "stage" "ingress" "services@" "SSH"
  3. iptables -S INPUT | grep dhcp_server_syslog — still present, above the catch-all DROP (previously it disappeared).
  4. pytest tests/caclmgrd/caclmgrd_preserved_input_rules_test.py

Which release branch to backport (provide reason below if selected)

  • 202511

The rule and the CACL flush-and-rebuild both exist on 202511 (the rule was added by sonic-net/sonic-buildimage#26637, included in 202511), so the same drop happens there.

Description for the changelog

[caclmgrd] Preserve externally-owned INPUT rules (e.g. the dhcp_server docker0 syslog rule, tagged by an iptables comment) across the control-plane ACL flush-and-rebuild.

@mssonicbld

Copy link
Copy Markdown

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@Xichen96
Xichen96 force-pushed the dev/xichenlin/caclmgrd-dhcp-server-syslog branch from 149cbfe to 68f7e81 Compare June 19, 2026 08:00
@mssonicbld

Copy link
Copy Markdown

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@Xichen96 Xichen96 changed the title [caclmgrd] Regenerate dhcp_server syslog rule during CACL rebuild [caclmgrd]: Preserve externally-owned INPUT rules across CACL rebuild Jun 19, 2026
@Xichen96
Xichen96 force-pushed the dev/xichenlin/caclmgrd-dhcp-server-syslog branch from 68f7e81 to 7a1650c Compare June 19, 2026 12:36
@mssonicbld

Copy link
Copy Markdown

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates caclmgrd (the host control-plane ACL manager) to preserve specific externally-owned iptables INPUT rules across the daemon’s flush-and-rebuild cycle, preventing those kernel-only rules (e.g., the dhcp_server docker0 syslog exception) from being silently removed after a CACL update.

Changes:

  • Add an allowlist (IGNORED_INPUT_RULE_COMMENTS) and logic to snapshot matching commented INPUT rules before a rebuild and re-add them early in the rebuilt chain.
  • Insert preserved rules into the generated iptables command sequence before any DROP rules are appended.
  • Add unit tests covering snapshot filtering, graceful failure, ordering relative to the catch-all DROP, and namespace scoping.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
scripts/caclmgrd Snapshots allowlisted commented INPUT rules pre-flush and re-inserts them early during CACL rebuild; adds helper get_preserved_input_rules().
tests/caclmgrd/caclmgrd_preserved_input_rules_test.py Adds unit tests validating preservation behavior, ordering before DROP, failure handling, and host-namespace-only behavior.

Comment thread scripts/caclmgrd
caclmgrd owns the host INPUT chain and flushes/rebuilds it from CONFIG_DB
on every control-plane ACL change. Rules installed by OTHER services live
only in the kernel and are silently wiped by that rebuild. The concrete
case is the dhcp_server container docker0 syslog (UDP 514) ACCEPT
(sonic-net/sonic-buildimage#27584): after any CACL update it is dropped
until dhcp_server restarts, breaking syslog from the bridge-mode container.

Make caclmgrd not clobber externally-owned INPUT rules. caclmgrd never
comments its own rules, so an iptables --comment is an unambiguous marker
of external ownership. Before the flush, snapshot any INPUT rule whose
--comment is in an explicit ignore list (IGNORED_INPUT_RULE_COMMENTS,
currently just "dhcp_server_syslog") and re-add it verbatim early in the
rebuild -- before the ip2me and catch-all DROPs. The INPUT policy is ACCEPT
throughout the rebuild and the catch-all DROP is appended last, so there is
no window where the rule is missing while a DROP exists; no syslog is lost.

The owning service keeps full lifecycle control: caclmgrd never creates or
deletes the rule, it only mirrors it, and re-adds it byte-identically so the
container own -C/-D keep matching. Host namespace / IPv4 only. No change to
the dhcp_server container.

Fixes sonic-net/sonic-buildimage#27584

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Xichen96 <lukelin0907@gmail.com>
@Xichen96
Xichen96 force-pushed the dev/xichenlin/caclmgrd-dhcp-server-syslog branch from 7a1650c to 80744ee Compare June 19, 2026 12:56
@mssonicbld

Copy link
Copy Markdown

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@Xichen96

Copy link
Copy Markdown
Contributor Author

@Bojun-Feng this addresses sonic-net/sonic-buildimage#27584 with a different approach than #390 — instead of caclmgrd regenerating the rule from FEATURE state, it preserves the externally-owned INPUT rule (identified by its iptables --comment) across the CACL flush-and-rebuild, so dhcp_server stays the sole owner and the container is unchanged. Would appreciate your review.

cc @tirupatihemanth @yejianquan @vmittal-msft @Sourabh-Kumar7 — review requests sent, feedback welcome.

@Xichen96

Copy link
Copy Markdown
Contributor Author

@StormLiangMS adding you for visibility — caclmgrd fix for the dhcp_server syslog drop after control-plane ACL updates (fixes sonic-net/sonic-buildimage#27584), with a 202511 backport requested. Happy to walk through the approach.

@tirupatihemanth

tirupatihemanth commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Hi @Xichen96 I understand that we are trying to preserve specific commented filtering rules here. Since dhcp container is in bridge networking and we will always need this rule for dhcp syslog traffic - can we make this as part of default CONFIG_DB instead of adding the rule preservation logic in caclmgrd?

The pov I am looking at is dhcp_server should modify kernel ip table rules through CONFIG_DB and not directly.
CMIIW

++ @StormLiangMS

@StormLiangMS
StormLiangMS requested a review from yyynini June 24, 2026 03:02

@yyynini yyynini left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One concern here:
get_preserved_input_rules() matches purely on --comment and replays the rule verbatim, without validating what it actually does (interface/protocol/port/action). Once a comment is in IGNORED_INPUT_RULE_COMMENTS, whatever rule carries that comment gets preserved as-is, indefinitely.

Would it make sense to validate the preserved rule's shape against an expected pattern per allowlist entry, rather than accepting whatever the kernel currently reports for that comment?

Not a hard blocker, but wanted to flag it.

@Xichen96
Xichen96 requested a review from Copilot July 6, 2026 16:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread scripts/caclmgrd

@tirupatihemanth tirupatihemanth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dhcp_server shouldn't modify kernel ip table rules directly using linux commands and should go through CONFIG_DB. That way we don't need this PR adding an exception to caclmgrd to skip those rules @Xichen96 please take a look

get_preserved_input_rules() silently skipped any `iptables -S` line that shlex.split()
could not parse. In practice this only happens when a preserved rule's --comment contains
an embedded newline, which fractures the -S output across lines; SONiC-owned, allowlisted
rules use single-line comments, so it effectively never fires. Log a warning if it ever
does, so a silently-unpreserved rule leaves a trace instead of vanishing on the next rebuild.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Xichen96 <lukelin0907@gmail.com>
@mssonicbld

Copy link
Copy Markdown

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@Xichen96
Xichen96 requested a review from yxieca July 7, 2026 12:04
@StormLiangMS

Copy link
Copy Markdown

@Xichen96 thanks for the detailed investigation. I agree the docker0 UDP/514 allow is needed: dhcp_server is intentionally bridge-mode and sends syslog to host rsyslog through docker0, while CACL can add a final INPUT DROP.

My concern is with preserving live iptables state by comment. That makes the kernel INPUT chain a second source of truth, and it can preserve stale or wrong-shape state if the rule lifecycle races with dhcp_server start/stop.

Could we make this feature-state driven instead? Specifically:

  • remove the direct iptables add/delete from dhcp_server startup in buildimage
  • have caclmgrd generate the narrow host-only docker0 UDP/514 ACCEPT rule when FEATURE|dhcp_server.state == enabled
  • trigger a host INPUT-chain rebuild when FEATURE|dhcp_server changes

That keeps caclmgrd as the single owner of host INPUT rules, avoids adding a synthetic CACL table for an internal syslog exception, and avoids changing dhcp_server to --net=$NET/host networking.

@Xichen96

Xichen96 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Closing — the approach in this PR is superseded.

After discussion we concluded that all iptables rules should be managed by caclmgrd. Rather than having caclmgrd preserve the externally-owned dhcp_server docker0 syslog (UDP 514) rule, caclmgrd will own it: it installs/removes the rule on every control-plane ACL flush-and-rebuild, keyed on FEATURE|dhcp_server (same pattern as the existing REDFISH gate), so the rebuild never drops it — fixing sonic-net/sonic-buildimage#27584 by construction.

Delivered as a 3-PR trio (parent ADO 38699922):

  1. [dhcp_server] Revert container-side docker0 syslog iptables add/del (#26637); caclmgrd to own the rule sonic-buildimage#28328 — revert the container-side iptables -I/-D add/del (#26637).
  2. (this repo, forthcoming) caclmgrd owns the rule based on FEATURE|dhcp_server — the direct successor to this PR.
  3. (sonic-buildimage, forthcoming) replace the container add/del with feature-gated bounded waits that synchronize with caclmgrd.

Superseded by the above; closing this one.

@Xichen96 Xichen96 closed this Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: CACL updates remove dhcp_server syslog iptables rule

7 participants